package base.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Environment
import android.text.TextUtils
import android.util.DisplayMetrics
import android.util.TypedValue
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import base.http.rxandroid.CustomObserver
import base.sys.PRODUCT_IMAGE_WEBP
import base.utils.StringUtils.isBlank
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.tange.ai.iot.client.gnssa.BuildConfig
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
import java.io.File
import java.math.BigDecimal
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern


/**
 * @author njmsir
 * Created by njmsir on 2017/8/21.
 */
object SysUtils {
    val isDebugEnvironment: Boolean
        get() = BuildConfig.DEBUG

    val REQUEST_PERMISSIONS_CODE = 100

    private var viewSize_W: Int = 0
    private var viewSize_H: Int = 0
    private var screenWidth: Int = 0
    private var screenHeight: Int = 0
    /**
     * 根据手机分辨率从dp单位转为px像素
     */
    @JvmStatic
    fun dp2px(context: Context, dpValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (dpValue * scale + 0.5f).toInt()
    }

    fun sp2px(context: Context, spValue: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spValue, context.resources.displayMetrics)
    }

    fun px2dp(context: Context, pxValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (pxValue / scale + 0.5f).toInt()
    }

    fun getString(context: Context, strArrId: Int): String? {
        val str = context.resources.getString(strArrId)
        return str
    }

    fun checkPermission(context: Context, permission: String): Boolean {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 隐藏软键盘的方法
     */
    fun hideInputForce(activity: Activity) {
        if (activity?.currentFocus == null) return
        (activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
                .hideSoftInputFromWindow(activity.currentFocus!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }

    /**
     * 获取屏幕宽度
     */
    @JvmStatic
    fun getScreenWidth(context: Context): Int {
        val displayMetrics = context.resources.displayMetrics
        return displayMetrics.widthPixels
    }

    /**
     * 获取屏幕高度
     */
    @JvmStatic
    fun getScreenHeight(context: Context): Int {
        val displayMetrics = context.resources.displayMetrics
        return displayMetrics.heightPixels
    }

    /**
     * 判断是否包含中文
     */
    fun isContainChinese(string: String): Boolean {
        val pattern = Pattern.compile("[\u4300-\u9fa5]")
        val matcher = pattern.matcher(string)
        if (matcher.find()) {
            return true
        }
        return false
    }

    /**
     * 通过Tag找到对应的Fragment
     */
    fun findFragment(activity: androidx.fragment.app.FragmentActivity, tag: String): androidx.fragment.app.Fragment {
        return activity.supportFragmentManager.findFragmentByTag(tag)!!
    }

    /**
     * 跳转activity页面
     */
    fun <T> goToNextPage(context: Context, pageClass: Class<T>) {
        val intent = Intent(context, pageClass)
        context.startActivity(intent)
    }

    fun getApplicationVersion(context: Context): String {
        var version = ""
        try {
            version = context.packageManager.getPackageInfo(context.packageName, 0).versionName
        } catch (e: PackageManager.NameNotFoundException) {
        }
        return version
    }

    fun getAppVersionCode(context: Context): Int {
        try {
            val pi = context.packageManager.getPackageInfo(context.packageName, 0)
            return pi.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
            return 0
        }

    }

    fun checkAndRequestPermissions(mContext: Activity, permissions: ArrayList<String>) {
        permissions.filter { ContextCompat.checkSelfPermission(mContext, it) != PackageManager.PERMISSION_GRANTED }
                .forEach { ActivityCompat.requestPermissions(mContext, arrayOf(it), REQUEST_PERMISSIONS_CODE) }
    }

    fun getProductModel(): String {
        return android.os.Build.MODEL
    }

    fun getProductModelVersion(): String {
        return android.os.Build.VERSION.RELEASE
    }

    /**
     * ETAO根据类型进行页面跳转
     */
//    fun goToNextScene(context: Context, listBean: ListBean) {
//        val scene = listBean.scene
//        if (TextUtils.isEmpty(scene)) {
//            return
//        }
//
//        val intent: Intent
//        when (scene) {
//            "ProductList" -> {
//                val paramsMap: HashMap<String, Any> = HashMap()
//                listBean.para?.forEach {
//                    if (!TextUtils.isEmpty(it.key) && !TextUtils.isEmpty(it.value)) {
//                        if (it.key == "sysid") {
//                            paramsMap.put(it.key!!, it.value!!.toInt())
//                        } else {
//                            paramsMap.put(it.key!!, it.value!!)
//                        }
//                    }
//                }
//                intent = Intent(context, ProductFilterActivity::class.java)
//                intent.putExtra("params", paramsMap)
//                context.startActivity(intent)
//            }
//
//            "InternationalBrand" -> {
//                intent = Intent(context, InternationalBrandActivity::class.java)
//                context.startActivity(intent)
//            }
//
//            "Classify" -> {
//                intent = Intent(context, HomeActivity::class.java)
//                intent.putExtra("showFragmentType", "classifyFragment")
//                context.startActivity(intent)
//            }
//
//            "WebSite" -> {
//                intent = Intent(context, WebActivity::class.java)
//                intent.putExtra("uri", listBean.para!![0].value)
//                context.startActivity(intent)
//            }
//
//            "BrandStore" -> {
//                intent = Intent(context, BrandShopActivity::class.java)
//                intent.putExtra("brandId", listBean.para!![0].value)
//                context.startActivity(intent)
//            }
//        }
//    }

    /**
     * 打电话
     */
    fun call(context: Context, phone: String) {
        val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone))
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        context.startActivity(intent)
    }

    /**
     * 与QQ指定用户聊天
     */
    fun callQQChat(context: Context, qqNum: String) {
        val url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qqNum
        context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
    }


    fun installApk(mContext: Context, path: String) {
        val intent = Intent(Intent.ACTION_VIEW)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.setDataAndType(Uri.fromFile(File(path)), "application/vnd.android.package-archive")
        mContext.startActivity(intent)
    }

    fun isMobileNum(mobiles: String): Boolean {
        val p = Pattern
                .compile("^1[123456789]\\d{9}$")
        val m = p.matcher(mobiles)
        return m.matches()
    }

    fun isEmail(strEmail: String): Boolean {
        val strPattern = "^[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$"
        if (TextUtils.isEmpty(strPattern)) {
            return false
        } else {
            return strEmail.matches(strPattern.toRegex())
        }
    }

    fun calculateHeight(imgUrl: String?, view: View) {
        Observable.create(ObservableOnSubscribe<Int> { emitter ->
            Glide.with(view.context)
                    .asBitmap()
                    .load(imgUrl + PRODUCT_IMAGE_WEBP)
                    .into(object : SimpleTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) {
                        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                            if (resource == null) {
                                emitter.onNext(dp2px(view.context, 200f))
                                return
                            }
                            val screenWidth = getScreenWidth(view.context)
                            val calculateImageHeight = screenWidth * resource.height / resource.width
                            emitter.onNext(calculateImageHeight)
                        }
                    })
        })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : CustomObserver<Int>(view.context) {
                    override fun onNext(t: Int) {
                        val layoutParams = view.layoutParams
                        layoutParams.height = t
                        layoutParams.width = getScreenWidth(view.context)
                    }
                })
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    fun dip2px(context: Context, dpValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (dpValue * scale + 0.5f).toInt()
    }

    fun getViewSize_W(mContext: Context,ratio: Float): Int {
        calculateW_H(mContext,ratio)
        return viewSize_W
    }

    fun calculateW_H(mContext: Context,ratio: Float) {
        val manager = mContext!!.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val dm = DisplayMetrics()
        manager.defaultDisplay.getMetrics(dm)
        val width = dm.widthPixels //屏幕宽
        val height = dm.heightPixels
        val calculateWidth = width * ratio
        val calculateHeight = height * ratio
        viewSize_W = calculateWidth.toInt()
        viewSize_H = calculateHeight.toInt()
        screenWidth = dm.widthPixels //屏幕宽
        screenHeight = dm.heightPixels
    }

    fun getViewSize_H(mContext: Context,ratio: Float): Int {
        calculateW_H(mContext,ratio)
        return viewSize_H
    }

//    fun getScreenWidth(mContext: Context,ratio: Float): Int {
//        calculateW_H(mContext,ratio)
//        return screenWidth
//    }

    /**
     * 判断某个服务是否正在运行的方法
     *
     * @param mContext
     * @param serviceName 是包名+服务的类名（例如：net.loonggg.testbackstage.TestService）
     * @return true代表正在运行，false代表服务没有正在运行
     */
    fun isServiceWork(mContext: Context, serviceName: String): Boolean {
        var isWork = false
        val myAM = mContext
                .getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val myList = myAM.getRunningServices(100)
        if (myList.size <= 0) {
            return false
        }
        val size = myList.size
        for (i in 0 until size) {
            val mName = myList[i].service.className.toString()
            if (mName == serviceName) {
                isWork = true
                break
            }
        }
        return isWork
    }

    fun getVersionCode(context: Context): Int {
        return try {
            val pi = context.packageManager.getPackageInfo(context.packageName, 0)
            pi.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
            0
        }

    }
    fun clearAllCache(context: Context) {
        deleteDir(context.cacheDir)
        if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
            deleteDir(context.externalCacheDir)
        }
    }
    private fun deleteDir(dir: File?): Boolean {
        if (dir != null && dir.isDirectory) {
            val children = dir.list()
            for (aChildren in children) {
                val success = deleteDir(File(dir, aChildren))
                if (!success) {
                    return false
                }
            }
        }
        assert(dir != null)
        return dir!!.delete()
    }


    /**
     * 确认更新版本是否比当前版本高
     *
     * @param currentVersion
     * @param upgradeVersion
     * @return
     */
    fun compareUpgradeVersionIsLager(
        currentVersion: String,
        upgradeVersion: String
    ): Boolean {
        if (isBlank(currentVersion) || isBlank(
                upgradeVersion
            )
        ) {
            return false
        }
        val currentVersionArray =
            currentVersion.split("\\.").toTypedArray()
        val upgradeVersionArray =
            upgradeVersion.split("\\.").toTypedArray()
        if (currentVersionArray.size < 0 || upgradeVersionArray.size < 0) {
            return false
        }
        var sameArrayCount = 0
        sameArrayCount = if (currentVersionArray.size > upgradeVersionArray.size) {
            upgradeVersionArray.size
        } else {
            currentVersionArray.size
        }
        for (i in 0 until sameArrayCount) {
            if (currentVersionArray[i].replace("[^\\d]".toRegex(), "")
                    .toLong() < upgradeVersionArray[i].replace("[^\\d]".toRegex(), "").toLong()
            ) {
                return true
            } else if (currentVersionArray[i].replace("[^\\d]".toRegex(), "")
                    .toLong() > upgradeVersionArray[i].replace("[^\\d]".toRegex(), "").toLong()
            ) {
                return false
            }
        }
        return if (currentVersionArray.size > upgradeVersionArray.size) {
            if (currentVersionArray.size >= sameArrayCount) {
                if (currentVersionArray[sameArrayCount].replace("[^\\d]".toRegex(), "")
                        .toLong() > 0
                ) {
                    false
                } else {
                    true
                }
            } else {
                false
            }
        } else if (upgradeVersionArray.size > currentVersionArray.size) {
            if (upgradeVersionArray.size >= sameArrayCount) {
                if (upgradeVersionArray[sameArrayCount].replace("[^\\d]".toRegex(), "")
                        .toLong() > 0
                ) {
                    true
                } else {
                    false
                }
            } else {
                false
            }
        } else {
            false
        }
    }

    fun getDate(stamp:String):String {
        var res=""
        var simpleDateFormat = SimpleDateFormat("yyyy.MM.dd");
        var lt =  stamp.toLong()*1000
        //将时间戳转换为时间
        var date = Date(lt)
        //将时间调整为yyyy-MM-dd HH:mm:ss时间样式
        res = simpleDateFormat.format(date)
        return res;
    }

    /**
     * 判断某个activity是否在前台显示
     */
    fun isForeground(activity: Activity): Boolean {
        return isForeground(activity, activity.javaClass.name)
    }

    /**
     * 判断某个界面是否在前台,返回true，为显示,否则不是
     */
    @SuppressLint("NewApi")
    fun isForeground(context: Activity?, className: String): Boolean {
        if (context == null || TextUtils.isEmpty(className))
            return false
        val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val list = am.getRunningTasks(1)
        if (list != null && list.size > 0) {
            val cpn = list[0].topActivity
            if (className == cpn!!.className)
                return true
        }
        return false
    }

    @Throws(Exception::class)
    fun getTotalCacheSize(context: Context): String {
        var cacheSize: Long = SysUtils.getFolderSize(context.cacheDir)
        if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
            cacheSize += getFolderSize(context.externalCacheDir!!)
        }
        return SysUtils.getFormatSize(cacheSize.toDouble())
    }

    private fun getFormatSize(size: Double): String {
        val kiloByte = size / 1024
        if (kiloByte < 1) {
            return "0K"
        }

        val megaByte = kiloByte / 1024
        if (megaByte < 1) {
            val result1 = BigDecimal(kiloByte.toString())
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
                .toPlainString() + "K"
        }

        val gigaByte = megaByte / 1024
        if (gigaByte < 1) {
            val result2 = BigDecimal(megaByte.toString())
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
                .toPlainString() + "M"
        }

        val teraBytes = gigaByte / 1024
        if (teraBytes < 1) {
            val result3 = BigDecimal(gigaByte.toString())
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
                .toPlainString() + "GB"
        }
        val result4 = BigDecimal(teraBytes)
        return (result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
                + "TB")
    }

    @Throws(java.lang.Exception::class)
    private fun getFolderSize(file: File): Long {
        var size: Long = 0
        try {
            val fileList = file.listFiles()
            for (aFileList in fileList) {
                // 如果下面还有文件
                size = if (aFileList.isDirectory) {
                    size + getFolderSize(aFileList)
                } else {
                    size + aFileList.length()
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return size
    }

}